package com.yanhui.modal.file;

import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import com.qiniu.util.UrlSafeBase64;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;


public class TokenGenerator {
	
	public static final String BUCKET = QiNiuConfig.BUCKET.getCode() ;
	
	// 简单上传，使用默认策略
	public static String getUpToken() {
		Auth auth = Auth.create(QiNiuConfig.AK.getCode(), QiNiuConfig.SK.getCode());
	    return auth.uploadToken(BUCKET);
	}
	
	public static String getUpToken1(String key) {
		
		Auth auth = Auth.create(QiNiuConfig.AK.getCode(), QiNiuConfig.SK.getCode());
		String tsPrefix = UrlSafeBase64.encodeToString(key+"$(count)"+".ts");
		key = QiNiuConfig.VIDEOPREFIX.getCode() + key ;
		String processName = UrlSafeBase64.encodeToString(BUCKET + ":" + key);
		CutConfig cutConfig = new CutConfig.BuilderCutConfig().setPattern(tsPrefix).build() ;
		String config = cutConfig.format(processName) ;
	    return auth.uploadToken(BUCKET, null, 3600, new StringMap().
		    		putNotEmpty("returnBody", "{\"key\": $(key), \"hash\": $(etag), \"persistentId\": $(persistentId)}").
		    		put("persistentOps", config)) ;
	    
	}
	
	/**
	 * 视频处理参数
	 */
	static class CutConfig {
		
		Map<String ,Object> cutConfig = new HashMap<String,Object>() ;
		
		private void setValue(String key , Object value) {
			if (value != null ) {
				this.cutConfig.put(key, value) ;
			}
		}
		
		public String format(String fileName) {
			StringBuffer sb = new StringBuffer() ;
			for (Entry<String, Object> item : this.cutConfig.entrySet()) {
				String key = item.getKey() ;
				String value = item.getValue().toString() ;
				sb.append(key).append("/").append(value).append("/") ;
			}
			sb.deleteCharAt(sb.lastIndexOf("/")) ;
			if (!StringUtils.isEmpty(fileName)) {
				sb.append("|").append("saveas/").append(fileName) ;
			}
			return sb.toString() ; 
		}
		
		public CutConfig(BuilderCutConfig config) {
			Field[] fields = BuilderCutConfig.class.getDeclaredFields() ;
			for (int i = 0 ; i < fields.length ; i++) {
				Field field = fields[i] ;
				field.setAccessible(true);
				String key = field.getName() ;
				try {
					Object value = field.get(config) ;
					this.setValue(key,value) ;
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			}
		}
		
		static class BuilderCutConfig {
			//处理头(默认为m3u8)
			private String avthumb = "m3u8";
			
			//用于自定义每一小段音/视频流的播放时长，单位：秒，取值范围5-120秒，默认值为10秒。
			private Integer segtime = 5 ;
			
			//静态码率（CBR），单位：比特每秒（bit/s），常用码率：64k，128k，192k，256k，320k等。
			private String ab ; 
			
			//动态码率（VBR），取值范围为0-9，值越小码率越高。不能与上述静态码率参数共用。
			private Integer aq ;
			
			//音频采样频率，单位：赫兹（Hz），常用采样频率：8000，12050，22050，44100等。
			private String ar ;
			
			//视频帧率，每秒显示的帧数，单位：赫兹（Hz），常用帧率：24，25，30等，一般用默认值。
			private Integer r = 24;
			
			//视频比特率，单位：比特每秒（bit/s），常用视频比特率：128k，1.25m，5m等。
//			private String vb = "128k";
			private String vb = "1.25m";
			
			//视频编码方案，支持方案：libx264，libvpx，libtheora，libxvid等。
			private String vcodec ;
			
			//音频编码方案，支持方案：libmp3lame，libfaac，libvorbis等。
			private String acodec ;
			
			//字幕的编码方案，支持方案：mov_text, srt, ass等。该参数仅用于修改带字幕视频的字幕编码。
			private String scodec ;
			
			//指定视频截取的开始时间，单位：秒。用于视频截取，从一段视频中截取一段视频。
			private Integer ss ;
			
			//指定视频截取的长度，单位：秒。用于视频截取，从一段视频中截取一段视频。
			private Integer t ;
			
			//指定视频分辨率，格式为<width>x<height>或者预定义值。
			private String s ; 
			
			//是否清除文件的metadata，1为清除，0为保留。
			private Integer stripmeta ;
			
			//指定顺时针旋转的度数，可取值为90、180、270、auto，默认为不旋转。
			private String rotate ;
			
			//取值为0或者1，不设置的情况下为0。表示切片索引中的切片列表，是否使用相对地址，设置为1则使用相对地址，设置为0则使用绝对地址。
			private Integer noDomain ;
			
			//AES128加密视频的秘钥，必须是16个字节
			private String hlsKey ;
			
			//秘钥传递给我们的方式，0或不填：, 1.x(1.0, 1.1, …): 见下面详细解释
			private String hlsKeyType ;
			
			//秘钥的访问url
			private String hlsKeyUrl ;
			
			//为各音视频流ts文件自定义命名。
			//因为一整个音视频流音视频切片后会生成一个M3U8播放列表和多个默认命名的音视频流ts文件。
			//示例：avthumb/m3u8/pattern/eGlhb3hpYW8kKGNvdW50KQ==，其中eGlhb3hpYW8kKGNvdW50KQ==是自定义ts文件名如qiniu$(count)的URL安全的Base64编码，其中$(count)是必须存在的六位占位符数字串，qiniu可以自己定义。最后得到类似qiniu000000qiniu000001……qiniu000006命名的ts文件。
			private String pattern ;
			
			public CutConfig build() { 
				 return new CutConfig(this) ;
			}

			public String getAvthumb() {
				return avthumb;
			}

			public BuilderCutConfig setAvthumb(String avthumb) {
				this.avthumb = avthumb;
				return this ;
			}

			public int getSegtime() {
				return segtime;
			}

			public BuilderCutConfig setSegtime(int segtime) {
				this.segtime = segtime;
				return this ;
			}

			public String getAb() {
				return ab;
			}

			public BuilderCutConfig setAb(String ab) {
				this.ab = ab;
				return this ;
			}

			public int getAq() {
				return aq;
			}

			public BuilderCutConfig setAq(int aq) {
				this.aq = aq;
				return this ;
			}

			public String getAr() {
				return ar;
			}

			public BuilderCutConfig setAr(String ar) {
				this.ar = ar;
				return this ;
			}

			public int getR() {
				return r;
			}

			public BuilderCutConfig setR(int r) {
				this.r = r;
				return this ;
			}

			public String getVb() {
				return vb;
			}

			public BuilderCutConfig setVb(String vb) {
				this.vb = vb;
				return this ;
			}

			public String getVcodec() {
				return vcodec;
			}

			public BuilderCutConfig setVcodec(String vcodec) {
				this.vcodec = vcodec;
				return this ;
			}

			public String getAcodec() {
				return acodec;
			}

			public BuilderCutConfig setAcodec(String acodec) {
				this.acodec = acodec;
				return this ;
			}

			public String getScodec() {
				return scodec;
			}

			public BuilderCutConfig setScodec(String scodec) {
				this.scodec = scodec;
				return this ;
			}

			public int getSs() {
				return ss;
			}

			public BuilderCutConfig setSs(int ss) {
				this.ss = ss;
				return this ;
			}

			public int getT() {
				return t;
			}

			public BuilderCutConfig setT(int t) {
				this.t = t;
				return this ;
			}

			public String getS() {
				return s;
			}

			public BuilderCutConfig setS(String s) {
				this.s = s;
				return this ;
			}

			public int getStripmeta() {
				return stripmeta;
			}

			public BuilderCutConfig setStripmeta(int stripmeta) {
				this.stripmeta = stripmeta;
				return this ;
			}

			public String getRotate() {
				return rotate;
			}

			public BuilderCutConfig setRotate(String rotate) {
				this.rotate = rotate;
				return this ;
			}

			public int getNoDomain() {
				return noDomain;
			}

			public BuilderCutConfig setNoDomain(int noDomain) {
				this.noDomain = noDomain;
				return this ;
			}

			public String getHlsKey() {
				return hlsKey;
			}

			public BuilderCutConfig setHlsKey(String hlsKey) {
				this.hlsKey = hlsKey;
				return this ;
			}

			public String getHlsKeyType() {
				return hlsKeyType;
			}

			public BuilderCutConfig setHlsKeyType(String hlsKeyType) {
				this.hlsKeyType = hlsKeyType;
				return this ;
			}

			public String getHlsKeyUrl() {
				return hlsKeyUrl;
			}

			public BuilderCutConfig setHlsKeyUrl(String hlsKeyUrl) {
				this.hlsKeyUrl = hlsKeyUrl;
				return this ;
			}

			public String getPattern() {
				return pattern;
			}

			public BuilderCutConfig setPattern(String pattern) {
				this.pattern = pattern;
				return this ;
			}
		}
		
	}
	
}
